package com.triangulator.gps;

import java.util.ArrayList;
import java.util.List;

import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.ece594bb.project.localization_and_reidentification.R;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.triangulator.Triangulator;

public class MyMapView extends MapActivity {
	private static String TAG="MyMapView";

	private MapView mapView;
	private Toast noLocation;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.map);

		mapView = (MapView) findViewById(R.id.mapview);
		mapView.setBuiltInZoomControls(true);
		
		noLocation = Toast.makeText(MyMapView.this, "No Locations Got, Yet!", Toast.LENGTH_LONG);
	}

	@Override	protected boolean isRouteDisplayed() 	{ return false; }

	@Override
	public void onStop() {
		super.onStop();
		
		noLocation.cancel();
	}
	
	
	@Override
	public synchronized void onResume() {
		super.onResume();

		Log.d(TAG, "+ ON RESUME +");
		
		Triangulator.spinningWheel.cancel();

		int my_list_size = Triangulator.allMyLocations.size();
		int other_list_size = Triangulator.allOtherLocations.size();

		if(my_list_size!=0 || other_list_size!=0)
		{
			int res_id = this.getResources().getIdentifier("icong"+(my_list_size+other_list_size), "drawable", "com.ece594bb.project.localization_and_reidentification");
			Drawable intersectdrawable;
			
			if(res_id == 0)
				intersectdrawable = this.getResources().getDrawable(R.drawable.icong);
			else
				intersectdrawable = this.getResources().getDrawable(res_id); 
			
			int draw_w = intersectdrawable.getIntrinsicWidth();
			int draw_h = intersectdrawable.getIntrinsicHeight();
			intersectdrawable.setBounds(-draw_w / 2, -draw_h, draw_w / 2, 0);

			Drawable otherdrawable = this.getResources().getDrawable(R.drawable.iconb);
			draw_w = otherdrawable.getIntrinsicWidth();
			draw_h = otherdrawable.getIntrinsicHeight();
			otherdrawable.setBounds(-draw_w / 2, -draw_h, draw_w / 2, 0);
			
			Drawable mydrawable = this.getResources().getDrawable(R.drawable.iconr);
			draw_w = mydrawable.getIntrinsicWidth();
			draw_h = mydrawable.getIntrinsicHeight();
			mydrawable.setBounds(-draw_w / 2, -draw_h, draw_w / 2, 0);
			
			List<Overlay> mapOverlays = mapView.getOverlays();
			MyItemizedOverlay itemizedoverlay = new MyItemizedOverlay(mydrawable, this);

			for(LatLong p : Triangulator.allOtherLocations)
			{
				OverlayItem otherLocation = new OverlayItem(p.getGeoPoint(), "Other Point", "");
				otherLocation.setMarker(otherdrawable);
				itemizedoverlay.addOverlay(otherLocation);
			}

			for(LatLong p : Triangulator.allMyLocations)
			{
				itemizedoverlay.addOverlay(new OverlayItem(p.getGeoPoint(), "My Point", ""));
			}

			GeoPoint intersect_point = calcIntersectionPoint(my_list_size + other_list_size);

//			String coordinates[] = {"0.352566007", "23.78921587"};
//			double lat = Double.parseDouble(coordinates[0]);
//			double lng = Double.parseDouble(coordinates[1]);
//
//			GeoPoint p1 = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
//			intersect_point=p1;

			if(intersect_point!=null) 
			{
				Log.d(TAG, "intersect point has been calculated");

				OverlayItem intersectLocation = new OverlayItem(intersect_point, "Intersection Point", "");
				intersectLocation.setMarker(intersectdrawable);
				itemizedoverlay.addOverlay(intersectLocation);
			}
			else
				Log.d(TAG, "NO intersect point has been calculated");

			mapOverlays.add(itemizedoverlay);


			mapView.getController().setZoom(18);

			if(intersect_point!=null)
			{
				int latSpan = 10;
				int lonSpan = 10;
				for (LatLong p : Triangulator.allMyLocations) {
					if (latSpan < Math.abs(p.getLatitudeE6()-intersect_point.getLatitudeE6()))
						latSpan = Math.abs(p.getLatitudeE6()-intersect_point.getLatitudeE6());

					if (lonSpan < Math.abs(p.getLongitudeE6()-intersect_point.getLongitudeE6()))
						lonSpan = Math.abs(p.getLongitudeE6()-intersect_point.getLongitudeE6());
				}
				for (LatLong p : Triangulator.allOtherLocations) {
					if (latSpan < Math.abs(p.getLatitudeE6()-intersect_point.getLatitudeE6()))
						latSpan = Math.abs(p.getLatitudeE6()-intersect_point.getLatitudeE6());

					if (lonSpan < Math.abs(p.getLongitudeE6()-intersect_point.getLongitudeE6()))
						lonSpan = Math.abs(p.getLongitudeE6()-intersect_point.getLongitudeE6());
				}
				mapView.getController().zoomToSpan(latSpan, lonSpan);

				mapView.getController().animateTo(intersect_point);
			}
			else if(my_list_size!=0)
				mapView.getController().animateTo(Triangulator.allMyLocations.get(0).getGeoPoint());
			else
				mapView.getController().animateTo(Triangulator.allOtherLocations.get(0).getGeoPoint());
		}
		else
		{
			noLocation.show();
		}
	}

	private GeoPoint calcIntersectionPoint(int total_size)
	{
		LatLong [] points = new LatLong[total_size];

		ArrayList<LatLong> allLocations = new ArrayList<LatLong>();

		allLocations.addAll(Triangulator.allMyLocations);
		allLocations.addAll(Triangulator.allOtherLocations);

		int list_size = allLocations.size();

		Log.d(TAG, "total # points: "+list_size);

		for(int i = 0; i < total_size; i++)
		{
			// can return a null point!
			points[i] = Intersection.intersect(allLocations.get(i), allLocations.get((i+1) % list_size));
		}

		return calcMediumPoint(points);
	}

	private GeoPoint calcMediumPoint(LatLong [] points)
	{
		int latitudeE6 = 0;
		int longitudeE6 = 0;
		int points_num=0;

		boolean gotAtLeast1 = false;

		for(LatLong p : points)
		{
			if(p!=null)
			{
				latitudeE6  = (latitudeE6  * points_num + p.getLatitudeE6()) /(points_num+1);
				longitudeE6 = (longitudeE6 * points_num + p.getLongitudeE6())/(points_num+1);

				points_num++;

				gotAtLeast1=true;
			}
		}

		Log.d(TAG, "num of points: "+ points_num + " medium = lat: " + latitudeE6 + " long: "+ longitudeE6);

		if(gotAtLeast1)
			return new GeoPoint(latitudeE6, longitudeE6);
		else
			return null;
	}
} 